home *** CD-ROM | disk | FTP | other *** search
- /* remote command server */
-
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "netuser.h"
- #include "timer.h"
- #include "tcp.h"
- #include "password.h"
- #include "rcmd.h"
- #include "cmdparse.h"
-
- static struct tcb *rcmd_tcb; /* SERVER prototype tcb */
- static char *rcmd_paswrd = NULLCHAR; /* password for rcmd */
-
- static struct mbuf *rcmdbuf = NULLBUF; /* output buffer for rcmdputc */
- static struct mbuf *rcmdout = NULLBUF; /* chain of rcmd output bufs */
-
- static void rcmd_recv(),rcmd_state();
- static int rcmdputc();
-
- extern char version[]; /* program version */
- extern char hostname[]; /* hostname to use in prompt */
- extern char prompt[]; /* the net> prompt */
- extern char nospace[]; /* "no space" message */
- extern struct cmds cmds[]; /* commands */
-
- /* Start up rcmd server */
- rcmd1(argc,argv)
- int argc;
- char *argv[];
- {
- struct socket lsocket;
- char tos = 0;
-
- if (rcmd_paswrd != NULLCHAR){
- free(rcmd_paswrd);
- rcmd_paswrd = NULLCHAR;
- }
-
- if (argc > 2){
- if ((rcmd_paswrd = malloc(strlen(argv[2]) + 1)) == NULLCHAR) {
- printf(nospace);
- return 1;
- }
- strcpy(rcmd_paswrd,argv[2]);
- }
-
- lsocket.address = ip_addr;
- if(argc < 2)
- lsocket.port = RCMD_PORT;
- else {
- if ((lsocket.port = atoi(argv[1])) == 0)
- lsocket.port = RCMD_PORT;
- }
- if(argc > 3)
- tos = get_tos(argv[3]);
- rcmd_tcb = open_tcp(&lsocket,NULLSOCK,TCP_SERVER,0,rcmd_recv,NULLVFP,rcmd_state,tos,(char *)NULL);
- return 0;
- }
-
- /* Shut down rcmd server */
- rcmd0()
- {
- if(rcmd_tcb != NULLTCB)
- close_tcp(rcmd_tcb);
-
- if (rcmd_paswrd != NULLCHAR){
- free(rcmd_paswrd);
- rcmd_paswrd = NULLCHAR;
- }
- return 0;
- }
-
- /* rcmd server receiver upcall */
- static
- void
- rcmd_recv(tcb,cnt)
- struct tcb *tcb;
- int16 cnt;
- {
- struct rcmd *rcmd;
- struct mbuf *bp;
- #ifdef MWC
- int (*save_pt)();
- #else
- # if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
- extern int (*put_stdout)();
- # else
- int c, save_handle;
- # ifdef MSC
- char *tmpfilename;
- # else
- char tmpfilename[L_tmpnam];
- # endif
- # endif
- #endif
- char cmdline[RCMD_LINE];
-
- rcmd = (struct rcmd *) tcb->user; /* get control block */
-
- if(recv_tcp(tcb,&bp,cnt) > 0){
- append(&rcmd->input,bp); /* append received bytes */
- tcp_output(tcb); /* ack the received data */
-
- fflush(stdout); /* make sure stdout is flushed */
-
- #ifdef MWC
- save_pt = stdout->_pt; /* save current stdout putc */
- stdout->_pt = rcmdputc; /* set stdout putc routine */
- #else
- # if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
- put_stdout = rcmdputc; /* set stdout putc routine */
- # else
- /* a portable way is to open a file on (ram) disk */
-
- save_handle = dup(fileno(stdout)); /* save stdout */
- # ifdef MSC
- tmpfilename = tempnam(NULL,"rcmd");
- # else
- tmpnam(tmpfilename);
- # endif
- freopen(tmpfilename,"w+b",stdout);
- # endif
- #endif
-
- while((bp = pullline(&rcmd->input,0)) != NULLBUF){
- cmdline[pullup(&bp,cmdline,sizeof(cmdline) - 1)] = '\0';
- free_p(bp);
- if (rcmd->pass.okay) {
- cmdparse(cmds,cmdline);
- printf("%s %s",hostname,prompt);
- } else {
- if (ok_password(&rcmd->pass,cmdline)) {
- log_tcp(tcb,"open rcmd %d",tcb->conn.local.port);
- printf("%s %s",hostname,prompt);
- } else {
- log_tcp(tcb,"fail rcmd %d",tcb->conn.local.port);
- printf("sorry\n");
- }
- }
- }
-
- #ifdef MWC
- stdout->_pt = save_pt;
- #else
- # if (defined(MSDOS) && !defined(MSC) && !defined(__TURBOC__))
- put_stdout = (int (*)()) 0; /* go back to default stdout */
- # else
- fseek(stdout,0L,0);
- while((c = getc(stdout)) != EOF)
- rcmdputc(c); /* copy tmpfile in rcmdbuffer */
-
- fseek(stdout,0L,0); /* don't write to disk */
- fflush(stdout);
- dup2(save_handle,fileno(stdout));
- unlink(tmpfilename); /* remove file */
- close(save_handle);
- # endif
- #endif
-
- append(&rcmdout,rcmdbuf);
- send_tcp(tcb,rcmdout);
- rcmdout = rcmdbuf = NULLBUF;
- }
-
- if (!rcmd->pass.okay)
- close_tcp(tcb);
- }
-
- /* character output routine for use in rcmd server */
- static
- int
- rcmdputc (c,outfile)
- int c;
- FILE *outfile;
- {
- if (c == '\n')
- rcmdputc('\r',outfile);
-
- if (rcmdbuf == NULLBUF &&
- (rcmdbuf = alloc_mbuf(RCMD_OBUF)) == NULLBUF)
- return EOF;
-
- rcmdbuf->data[rcmdbuf->cnt++] = c;
-
- if (rcmdbuf->cnt >= rcmdbuf->size){
- append(&rcmdout,rcmdbuf);
- rcmdbuf = NULLBUF;
- }
-
- return (c);
- }
-
- /* Log connection state changes; also respond to remote closes */
- static
- void
- rcmd_state(tcb,old,new)
- register struct tcb *tcb;
- char old,new;
- {
- char buf[256];
- struct rcmd *rcmd;
-
- switch(new){
- case ESTABLISHED:
- if((rcmd = (struct rcmd *) calloc(1,sizeof(struct rcmd))) == NULLRCMD){
- /* No space, kill connection */
- close_tcp(tcb);
- return;
- }
- rcmd->conn = tcb; /* Downward link */
- tcb->user = (char *)rcmd; /* Upward link */
-
- if ((rcmd->pass.paswrd = rcmd_paswrd) == NULLCHAR){
- log_tcp(tcb,"open rcmd %d (no pw)",tcb->conn.local.port);
- rcmd->pass.okay = 1;
- sprintf(buf,"rcmd %s\r\n%s %s",version,hostname,prompt);
- } else {
- sprintf(buf,"rcmd %s %s\r\n%s\r\n",version,hostname,
- gen_challenge(&rcmd->pass));
- }
- send_tcp(tcb,qstring(buf));
- break;
- case CLOSE_WAIT:
- close_tcp(tcb);
- break;
- case CLOSED:
- if(tcb != rcmd_tcb)
- log_tcp(tcb,"close rcmd %d",tcb->conn.local.port);
- if (tcb->user != NULLCHAR)
- free(tcb->user);
- del_tcp(tcb);
- /* Clean up if server is being shut down */
- if(tcb == rcmd_tcb)
- rcmd_tcb = NULLTCB;
- break;
- }
- }
-